<?php
/**
 * Created by PhpStorm.
 * User: stc17
 * Date: 2020/3/5
 * Time: 13:24
 */

namespace SwoCloud\Server;

use SwoCloud\Supper\Arithmetic;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Server as SwooleServer;

use \Firebase\JWT\JWT;

class Dispatcher
{
    public function register(Route $route,SwooleServer $server,$fd,$data)
    {
        dd('register','Dispatcher');
        $serverKey=$route->getServerKey();
        //把服务端的信息记录到redis中
        $redis=$route->getRedis();
        $value=json_encode([
            'ip'    =>$data['ip'],
            'port'  =>$data['port'],
        ]);
        $redis->sadd($serverKey,$value);

        // 这里是通过触发定时判断，不用heartbeat_check_interval 的方式检测
        // 是因为我们还需要主动清空，redis 数据
        //
        // $timer_id 定时器id
        $server->tick(3000,function ($timer_id,$redis,$server,$serverKey,$fd,$value){
            //定时判断im-server连接是否正常运行，如果不是就主动清空，并把信息从redis中清空
            if(!$server->exist($fd))
            {
                $redis->srem($serverKey,$value);
                $server->clearTimer($timer_id);

                dd('im server 宕机,主动清空');
            }
        },$redis,$server,$serverKey,$fd,$value);
    }


    //route向im-server广播
    public function routeBroadcast(Route $route,SwooleServer $server,$fd,$data)
    {

       // dd($data,'接收到im-server client 的信息');

        //获取所有服务器
        $imServers=$route->getIMServers();

        $token=$this->getJwtToken(0,$route->getHost().':'.$route->getPort());
        $header=['sec-websocket-protocol'=>$token];
        foreach ($imServers as $key =>$im){
            $imInfo=json_decode($im,true);
            //转发给其他服务器
            $route->send($imInfo['ip'],$imInfo['port'],[
                'method'=>'routeBroadcast',
                'data'=>[
                    'msg'=>$data['msg']
                ]
            ],$header);

        }

    }

    public function login(Route $route,Request $request,Response $response){


        //获取im-server服务器
        /*192.168.157.240：9000
         * */
        $imServer=\json_decode($this->getIMServer($route),true);
       // dd($imServer,'这是获取的服务器信息');

        $url=$imServer['ip'].":".$imServer['port'];
        //去数据库中进行用户密码账号验证

        $uid=$request->post['id'];
        $token=$this->getJwtToken($uid,$url);
        //dd($token,'生成的token');
        $response->end(\json_encode(['token'=>$token,'url'=>$url]));
    }

    public function getJwtToken($uid,$url)
    {
        $key = "swocloud";
        $time=\time();
        $payload = array(
            "iss" => "http://example.org",
            "aud" => "http://example.com",
            "iat" => $time,//签发时间
            "nbf" => $time,//生效事件
            "exp"=>$time+(60*60*24),
            "data"=>[
                "uid"=> $uid,
                "name"=>'client'.$uid,
                "serverUrl"=>$url
            ],
        );

       return JWT::encode($payload, $key);
       // $decoded = JWT::decode($jwt, $key, array('HS256'));
    }
    protected function getIMServer(Route $route)
    {
        //读取redis中所有imserver服务信息
        $imServers=$route->getIMServers();
       if(!empty($imServers)){
          return  Arithmetic::{$route->getArithmetic()}($imServers);
       }
        return false;
    }
}